package com.ruoyi.push;

import com.ruoyi.alarm.domain.AlarmWarning;
import com.ruoyi.alarm.service.IAlarmPushService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.websocket.vo.WsMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息推送服务,异步，避免数据库事务或阻塞
 */
@Service
@Slf4j
public class PushService {
    public static Map<String, PushChannel> channelMap = new ConcurrentHashMap<>();
    public static final String DATE_FORMAT = "yyyy年MM月dd日 HH点mm分ss秒";
    @Autowired
    private IAlarmPushService alarmPushService;

    /**
     * 推送告警
     * @param alarmWarning
     */
    @Async("threadPoolTaskExecutor")
    public void pushAlarm(AlarmWarning alarmWarning){
        List<PushUser> list = alarmPushService.alarmPushUser(alarmWarning);
        if(list == null || list.isEmpty()){
            return;
        }
        String alarmTime = DateUtils.parseDateToStr(DATE_FORMAT, alarmWarning.getAlarmTime());
        String msg = String.format("%s 在 %s 发生 %s 告警", alarmWarning.getPosition(), alarmTime, alarmWarning.getComment());
        WsMessage message = WsMessage.create(WsMessage.ALARM, msg, alarmWarning.getAlarmTime().getTime());
        message.setObjectType("alarm");
        message.setObjectId(alarmWarning.getId());

        push(message, list);
    }

    /**
     * 推送告警处置
     * @param alarmWarning
     */
    @Async("threadPoolTaskExecutor")
    public void pushHandle(AlarmWarning alarmWarning){
        List<PushUser> list = alarmPushService.alarmPushUser(alarmWarning);
        if(list == null || list.isEmpty()){
            return;
        }

        String alarmTime = DateUtils.parseDateToStr(DATE_FORMAT, alarmWarning.getAlarmTime());
        String msg = String.format("%s 在 %s 发生的 %s 告警已处置", alarmWarning.getPosition(), alarmTime, alarmWarning.getComment());
        WsMessage message = WsMessage.create(WsMessage.ALARM, msg, alarmWarning.getAlarmTime().getTime());
        message.setObjectType("handle");
        message.setObjectId(alarmWarning.getId());

        push(message, list);
    }

    /**
     * 推送消息
     * @param message
     * @param users
     */
    public void push(WsMessage message, List<PushUser> users){
        for(PushUser user:users){
            PushChannel channel = getChannel(user.getPushType());
            if(channel == null){
                log.error("不支持的消息推送渠道: {}", user.getPushType());
                continue;
            }

            if(user.getUserId().equals(0L)){
                channel.pushMessage(message);
            }else{
                channel.pushMessage(user, message);
            }
        }
    }

    /**
     * 获取消息推送渠道
     * @param pushType
     * @return
     */
    public PushChannel getChannel(String pushType){
        PushChannel channel = channelMap.get(pushType);
        if(channel != null){
            return channel;
        }
        channel = SpringUtils.getBean(pushType+"Push");
        if(channel != null){
            channelMap.put(pushType, channel);
        }
        return channel;
    }
}
